package org.six11.olive3.picturephone;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

import org.six11.olive3.util.MultiState;
import org.six11.util2.Debug;
import org.six11.util2.gui.ApplicationFrame;
import org.six11.util2.layout.FrontEnd;
import org.six11.util2.layout.Holder;
import org.six11.util2.lev.NamedAction;

/**
 * 
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public class PicturephoneControlBox extends FrontEnd {

  private static void bug(String what) {
    Debug.out("PicturephoneControlBox", what);
  }

  private MultiState programState;
  private JLabel scoreLabel;
  private JLabel messageLabel;
  private JCheckBox sketchCB;
  private JCheckBox describeCB;
  private JCheckBox rateCB;
  private Holder doneHolder;
  private Holder skipHolder;

  private String DEFAULT_MSG_VALUE = "Version 2";
  
  public PicturephoneControlBox(Action skipAction, Action doneAction, final MultiState programState) {
    this.programState = programState;
    JButton skipButton = new JButton(skipAction);
    JButton doneButton = new JButton(doneAction);
    scoreLabel = new JLabel();
    scoreLabel.setFont(new Font("Dialog", Font.PLAIN, 32));
    messageLabel = new JLabel();
    JPanel prefs = initPrefsPanel();

    String SKIP = "skip";
    String DONE = "done";
    String SCORE = "score";
    String MSG = "message";
    String PREFS = "prefs";

    doneHolder = new Holder(doneButton);
    skipHolder = new Holder(skipButton);

    programState.addChangeListener(ProgramStateConstants.K_PLAY_MODE, new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent ev) {
        boolean showIt = !programState.getValue(ProgramStateConstants.K_PLAY_MODE).equals(
            ProgramStateConstants.V_PLAY_MODE_RATE);
        doneHolder.setComponentVisible(showIt);
        skipHolder.setComponentVisible(showIt);
      }
    });

    PropertyChangeListener pcl = new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent ev) {
        whackLabels();
      }
    };
    programState.addChangeListener(ProgramStateConstants.K_SCORE, pcl);
    programState.addChangeListener(ProgramStateConstants.K_SCORE_REASON, pcl);
    programState.addChangeListener(ProgramStateConstants.K_PLAY_MODE_PREF_DESCRIBE, pcl);
    programState.addChangeListener(ProgramStateConstants.K_PLAY_MODE_PREF_SKETCH, pcl);
    programState.addChangeListener(ProgramStateConstants.K_PLAY_MODE_PREF_RATE, pcl);

    add(doneHolder, DONE);
    add(skipHolder, SKIP);
    add(scoreLabel, SCORE);
    add(messageLabel, MSG);
    add(prefs, PREFS);

    addRule(ROOT, N, DONE, N);
    addRule(ROOT, E, DONE, E);
    addRule(ROOT, N, SKIP, N);
    addRule(DONE, W, SKIP, E);

    addRule(ROOT, N, SCORE, N, 12);
    addRule(ROOT, W, SCORE, W, 12);

    addRule(ROOT, S, PREFS, S);
    addRule(ROOT, W, PREFS, W);
    addRule(ROOT, E, PREFS, E);

    addRule(PREFS, N, MSG, S);
    addRule(ROOT, W, MSG, W, 12);
    addRule(ROOT, E, MSG, E);
    addRule(SCORE, S, MSG, N);

    setPreferredSize(new Dimension(400, 100));
    whackLabels();
  }

  private void whackLabels() {
    String scoreVal = " ? ";
    String msgVal = DEFAULT_MSG_VALUE;

    if (programState.hasValue(ProgramStateConstants.K_SCORE)) {
      scoreVal = "" + programState.getValue(ProgramStateConstants.K_SCORE);
    }
    scoreLabel.setText("Score: " + scoreVal);

    if (programState.hasValue(ProgramStateConstants.K_SCORE_REASON)) {
      msgVal = programState.getString(ProgramStateConstants.K_SCORE_REASON);
    }
    messageLabel.setText(msgVal);

    if (programState.hasValue(ProgramStateConstants.K_PLAY_MODE_PREF_DESCRIBE)) {
      boolean b = (Boolean) programState.getValue(ProgramStateConstants.K_PLAY_MODE_PREF_DESCRIBE);
      describeCB.setSelected(b);
    }
    if (programState.hasValue(ProgramStateConstants.K_PLAY_MODE_PREF_SKETCH)) {
      boolean b = (Boolean) programState.getValue(ProgramStateConstants.K_PLAY_MODE_PREF_SKETCH);
      sketchCB.setSelected(b);
    }
    if (programState.hasValue(ProgramStateConstants.K_PLAY_MODE_PREF_RATE)) {
      boolean b = (Boolean) programState.getValue(ProgramStateConstants.K_PLAY_MODE_PREF_RATE);
      rateCB.setSelected(b);
    }
  }

  private JPanel initPrefsPanel() {
    JPanel ret = new JPanel();
    ret.setLayout(new FlowLayout());

    sketchCB = new JCheckBox();

    NamedAction action = new NamedAction("Sketch") {
      public void activate() {
        programState.setValue(ProgramStateConstants.K_PLAY_MODE_PREF_SKETCH, sketchCB.isSelected());
      }
    };
    sketchCB.setAction(action);
    sketchCB.setSelected(true);

    describeCB = new JCheckBox();
    action = new NamedAction("Describe") {
      public void activate() {
        programState.setValue(ProgramStateConstants.K_PLAY_MODE_PREF_DESCRIBE, describeCB
            .isSelected());
      }
    };
    describeCB.setAction(action);
    describeCB.setSelected(true);

    rateCB = new JCheckBox();
    action = new NamedAction("Rate") {
      public void activate() {
        programState.setValue(ProgramStateConstants.K_PLAY_MODE_PREF_RATE, rateCB.isSelected());
      }
    };
    rateCB.setAction(action);
    rateCB.setSelected(true);

    ret.add(new JLabel("I prefer to..."));
    ret.add(sketchCB);
    ret.add(describeCB);
    ret.add(rateCB);
    return ret;
  }

}
